package com.sk.rpcAssistNetty.io.netty.codec;

import com.sk.rpcAssistNetty.io.protocol.SerializeProtocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * description：解码器，数据包的第一个int类型是content的长度
 *
 * @author 孙文斌
 * @Date: 2021/3/22 14:41
 */
public class RpcDecoder extends ByteToMessageDecoder {
    private Class<?> clazz;
    private SerializeProtocol serializeProtocol;

    public RpcDecoder(Class<?> clazz, SerializeProtocol serializeProtocol) {
        this.clazz = clazz;
        this.serializeProtocol = serializeProtocol;
    }

    //todo：总结byteTomessageDecoder发生拆包时读不完整的时候，怎么缓存数据，下次读的时候从哪个位置开始读呢
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
//        System.out.println("netty 服务端decode被调用");
        if(in.readableBytes()<4){
            return;
        }
        //标记当前读的位置
        in.markReaderIndex();
        //数据包长度
        int dataLength = in.readInt();//===这里如果发生拆包不够int长度的数据，会怎么样
        //数据包发生了半包，读不完整，
        if(in.readableBytes()<dataLength){
            in.resetReaderIndex();//将读指针重置到前面标记位置
            return;
        }
        byte[] data = new byte[dataLength];
        //读到一个完整的数据包
        in.readBytes(data);
        //将此数据包反序列化成对象
        Object obj = serializeProtocol.deserialize(clazz, data);
        out.add(obj);
    }
}
